<template>
    <div v-loading="loading" element-loading-text="拼命加载中">
        <div>
            <el-input style="width: 200px" placeholder="查询用户账号" v-model="username"></el-input>
            <el-input style="width: 200px; margin: 0 5px" placeholder="查询用户姓名" v-model="name"></el-input>
            <el-button type="primary" @click="load(1)">查询</el-button>
            <el-button type="success" @click="reset">刷新</el-button>
        </div>
        <div style="margin: 10px 0">
            <el-button type="primary" plain @click="handleAdd">新增</el-button>
            <el-button type="danger" plain @click="handleDelBatch">批量删除</el-button>
            <el-button type="info" plain @click="exportBatch">批量导出</el-button>
            <el-upload :action="this.$apiUrl+'/user/importExcel'" style="display: inline-block; margin-left: 10px" :headers="{token: user.token}" :on-success="handleImport" :show-file-list="false">
                <el-button type="primary" plain>批量导入</el-button>
            </el-upload>
            <el-button type="info" plain @click="downloadTemplate" style="margin-left: 10px">下载导入模板</el-button>
        </div>
        <!--  整个表格，有多选框 -->
        <el-table :data="tableData" stripe :header-cell-style="{backgroundColor: 'aliceblue',color: '#666'}" @selection-change="handleSelectionChange">
            <!--    复选框-->
            <el-table-column type="selection" width="55" align="center"></el-table-column>
            <el-table-column prop="id" label="序号" width="80" align="center"></el-table-column>
            <el-table-column prop="username" label="账号"></el-table-column>
            <!--    <el-table-column prop="password" label="密码"></el-table-column>-->
            <el-table-column prop="name" label="姓名"></el-table-column>
            <el-table-column prop="phone" label="手机"></el-table-column>
            <el-table-column prop="email" label="邮箱"></el-table-column>
            <el-table-column label="头像">
                <template v-slot="scope">
                    <div style="display: flex;align-items: center">
                        <el-image v-if="scope.row.avatar" :src="scope.row.avatar" style="width: 50px;height: 50px;border-radius: 50%" :preview-src-list="[scope.row.avatar]"></el-image>
                    </div>
                </template>
            </el-table-column>
            <el-table-column prop="role" label="角色"></el-table-column>
            <el-table-column prop="state" label="账号状态" width="150">
                <template v-slot="scope">
                    <el-tag :type="getStatusType(scope.row.state)">{{getStatusText(scope.row.state)}}</el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="computer" label="电脑状态" width="150">
                <template v-slot="scope">
                    <el-tag :type="getStatusType(scope.row.computer)" @click="showChangeStatusDialog(scope.row)">{{getComputerText(scope.row.computer)}}</el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="creatTime" label="创建时间"></el-table-column>
            <el-table-column prop="updateTime" label="变更时间"></el-table-column>
            <el-table-column fixed="right" label="操作" align="center" width="180px">
                <template v-slot="scope">
                    <el-button size="mini" type="primary" plain @click="handleEdit(scope.row)">编辑</el-button>
                    <el-button size="mini" type="danger" plain @click="handleDel(scope.row)">删除</el-button>
                </template>
            </el-table-column>
        </el-table>

        <div style="margin: 10px 0;text-align: center">
            <!-- :page-sizes="[100,200,300,400]" -->
            <el-pagination @current-change="handleCurrentChange" :current-page="pageNum" :page-size="pageSize" layout="total,prev,pager,next" :total="total">
            </el-pagination>
        </div>

        <!-- 新增表单需要弹窗包裹 -->
        <el-dialog title="用户信息"
                   :visible.sync="formVisible"
                   width="30%"
                   @close="closeDialog" >
            <el-form :model="form" label-width="80px" style="padding-right: 20px" :rules="rules" ref="formRef">
                <div style="margin: 15px;text-align: center" v-loading="avatarLoad">
                    <el-upload class="avatar-uploader"
                               :action="this.$apiUrl+'/file/upload'"
                               :headers="{token: user.token}"
                               :show-file-list="false"
                               :before-upload="beforeAvatarUpload"
                               :on-success="handleAvatarSuccess">
                        <img v-if="form.avatar" :src="form.avatar" class="avatar">
                        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
                        <!--    可换一种头像显示方式    -->
                        <!--            <el-button type="primary">上传头像</el-button>-->
                    </el-upload>
                </div>

                <el-form-item label="账号" prop="username">
                    <el-input v-model="form.username" placeholder="账号" :disabled="isEditMode"></el-input>
                </el-form-item>

                <el-form-item label="姓名" prop="name">
                    <el-input v-model="form.name" placeholder="姓名"></el-input>
                </el-form-item>

                <el-form-item label="电话" prop="phone">
                    <el-input v-model="form.phone" placeholder="手机号"></el-input>
                </el-form-item>

                <el-form-item label="邮箱" prop="email">
                    <el-input v-model="form.email" placeholder="xxx@sangu.js.cn"></el-input>
                </el-form-item>

                <el-form-item label="头像">
                    <el-input v-model="form.avatar" placeholder="头像图片地址填入这里"></el-input>
                </el-form-item>

                <el-form-item label="地址" prop="address">
                    <el-input type="textarea" v-model="form.address" placeholder="江苏省 无锡市"></el-input>
                </el-form-item>

                <el-form-item label="权限" prop="role">
                    <el-radio-group v-model="form.role">
                        <el-radio label="用户"></el-radio>
                        <el-radio label="管理员"></el-radio>
                    </el-radio-group>
                </el-form-item>

            </el-form>

            <div slot="footer" class="dialog-footer">
                <el-button @click="formVisible = false">取消</el-button>
                <el-button type="primary" @click="save" :loading="saveLoad">保存</el-button>
            </div>
        </el-dialog>

        <!-- 添加弹窗组件 -->
        <el-dialog 
            :title="'修改 ' + currentRow.username + ' 的电脑状态'" 
            :visible.sync="changeStatusDialogVisible" 
            width="20%"
            modal-append-to-body
            append-to-body>
            <el-form :model="changeStatusForm" label-width="80px">
                <el-form-item label="当前状态">
                    <el-tag :type="currentRow.computer === 1 ? 'success' : 'danger'">
                        {{getComputerText(currentRow.computer)}}
                    </el-tag>
                </el-form-item>
                <el-form-item label="操作">
                    <el-button 
                        v-if="currentRow.computer === 1" 
                        type="danger" 
                        @click="submitChangeStatus(2)">
                        离线(关机)
                    </el-button>
                    <el-button 
                        v-else-if="currentRow.computer === 2" 
                        type="success" 
                        @click="submitChangeStatus(1)">
                        上线(开机)
                    </el-button>
                </el-form-item>
            </el-form>
            <span slot="footer" class="dialog-footer">
                <el-button @click="changeStatusDialogVisible = false">取消</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
export default {
    name: 'User',
    data() {
        return {
          loading: true,
          tableData: [], //表数据
          pageNum: 1, //当前页码
          pageSize:8, //每页数量
          username: '',
          name: '',
          total: 0, //数据总条数
          formVisible: false, //默认不显示新增表单弹窗
          form: {},
          user: JSON.parse(localStorage.getItem('userInfo') || '{}'),
          rules: {
              //校验规则
              username: [
                  {
                      required: true,
                      message: '输入账号，带 * 是必填项',
                      trigger: 'blur',
                  }, //必填，离开时触发校验
                  {
                      min: 1,
                      max: 10,
                      message: '长度在 1 到 10 个字符',
                      trigger: 'blur',
                  },
              ],
          },
          ids: [],
          isEditMode: false, //编辑模式
          avatarLoad: false,
          saveLoad: false,
          changeStatusDialogVisible: false, // 电脑状态修改弹窗
          currentRow: {}, // 当前选中的行数据
          changeStatusForm: { // 电脑状态修改表单
            newStatus: '', // 新状态
          },
        }
    },
    created() {
        // setTimeout(() => {
        //     this.loading = false
        // }, 3000)

        this.load()
    },
    methods: {
        reset() {
            this.username = ''
            this.name = ''
            this.load()
        },
        load(pageNum) {
            this.loading = true
            if (pageNum) this.pageNum = pageNum //分页查询时自动切换到第一页
            this.$request
                .get('/user/findByPage', {
                    params: {
                        pageNum: this.pageNum,
                        pageSize: this.pageSize,
                        username: this.username,
                        name: this.name,
                    },
                })
                .then((res) => {
                    // this.tableData = res.data
                    if (!res.data.records) {
                        alert('User.vue-records异常，如多次发生请联系管理员')
                    }
                    this.tableData = res.data.records //若records不显示可替换为List
                    this.total = res.data.total
                    this.loading = false
                })
        },
        //切换页码
        handleCurrentChange(pageNum) {
            // this.pageNum = pageNum //方法传递过来参数就不用赋值了
            this.load(pageNum)
        },
        showChangeStatusDialog(row) {
            if (row.computer === 0) {
                this.$message.warning('请先联系管理员绑定电脑');
                return;
            }
            this.currentRow = row;
            this.changeStatusDialogVisible = true;
            this.changeStatusForm.newStatus = row.computer;
        },
        submitChangeStatus(newStatus) {
            this.$request({
                method: 'PUT',
                url: '/user/updateComputerStatus',
                data: {
                    id: this.currentRow.id,
                    computer: newStatus
                }
            }).then(res => {
                if (res.code === '200') {
                    this.$message.success('操作成功');
                    this.currentRow.computer = newStatus;
                    this.changeStatusDialogVisible = false;
                    this.load(this.pageNum);
                } else {
                    this.$message.error(res.msg);
                }
            }).catch(error => {
                this.$message.error('操作失败');
            });
        },
        //更新头像成功
        handleAvatarSuccess(res, file, fileList) {
          this.avatarLoad = false;
          if (res.code==="200"){
            //更新表单中头像字段的链接
            this.$set(this.form, 'avatar', res.data.fileUrl)
          }else {
            this.$message.error(res.msg)
            if (res.code === "401"){
              this.$router.push('/login')
            }
          }
        },
        //上传头像之前
        beforeAvatarUpload(file){
          this.avatarLoad = true
          const fileType = file.type;
          const isJPG = fileType === 'image/jpeg' || fileType === 'image/png';
          const isLt2M = file.size / 1024 / 1024 < 20;
          if (!isJPG){
            this.$message.error('头像图片暂时只支持jpg/jpeg/png格式！')
            this.avatarLoad = false
          }
          if (!isLt2M){
            this.$message.error('头像图片文件大小不要超过20MB！')
            this.avatarLoad = false
          }
          return isJPG && isLt2M
        },
        //新增弹窗事件
        handleAdd() {
            this.form = { role: '用户' } //新增数据时清空表单
            this.isEditMode = false //非编辑模式
            this.formVisible = true //显示弹窗
        },
        //新增用户保存(包括编辑模式)
        save() {
            //校验表单
            // 根据数组form名称找到这个校验对象
            // this.$refs[formName].validate((valid) => {
            this.$refs.formRef.validate((valid) => {
                if (valid) {
                    this.saveLoad = true
                    this.$request({
                        //有id就是编辑
                        method: this.form.id ? 'PUT' : 'POST',
                        data: this.form,
                        url: this.form.id ? '/user/update' : '/user/save',
                    }).then((res) => {
                        if (res.code === '200') {
                            //保存成功
                            this.$message.success('保存成功')
                            //更新本地缓存信息，要存字符串
                            // localStorage.setItem('userInfo',JSON.stringify(this.form))
                            //更新后新头像通过子传父的方式通信给manager外框架去更新
                            //需加判断条件，否则任何人保存时右上角头像和名字信息都会被替换
                            //只有更新自己信息时需要替换，其他时候不需要
                            if (this.user.id === this.form.id){
                              this.$emit('update:user',this.form)
                            }
                            this.formVisible = false
                            this.load(this.pageNum)
                        } else {
                            this.$message.error(res.msg) //错误信息
                            return false
                        }
                        this.saveLoad = false
                    })
                } else {
                    this.$message.warning('表单校验未通过')
                    return false
                }
            })
        },
        //编辑用户信息
        handleEdit(row) {
            this.form = JSON.parse(JSON.stringify(row)) //弹窗带出来信息,浅拷贝是内存指向，深拷贝是开区域赋值
            this.isEditMode = true //编辑模式
            this.formVisible = true //打开弹窗
        },
        //单个删除用户
        handleDel(row) {
            this.$confirm('确认删除[' + row.name + ']用户吗？', '确认删除', {
                type: 'warning',
            })
                .then((ok) => {
                    this.$request
                        .delete('/user/delete/' + row.id)
                        .then((res) => {
                            if (res.code == '200') {
                                this.$message.success('删除成功')
                            } else {
                                this.$message.error('删除失败：' + res.msg)
                            }
                            this.load(this.pageNum) //刷新表格
                        })
                })
                .catch(() => {}) //catch捕捉先不做处理
        },
        //批量删除用户之前--多选框，参数是选中的行对象
        handleSelectionChange(rows) {
            this.ids = rows.map((row) => row.id) //流和表达式，将行id提取出来存入数组
        },
        //批量删除用户
        handleDelBatch() {
            //校验：点击批量删除按钮之前，未选择多选框时提示
            if (!this.ids.length) {
                this.$message.warning('请选择需要批量删除的用户！')
                return
            }

            this.$confirm(
                '你确认批量删除[' + this.ids + ']这些用户吗？',
                '确认删除',
                { type: 'warning' }
            )
                .then((ok) => {
                    // this.$request.delete('/user/deleteBatch',this.ids).then(res => {   //注意：不能直接通过url来传参，需要有配置对象
                    this.$request
                        .delete('/user/deleteBatch', { data: this.ids })
                        .then((res) => {
                            if (res.code == '200') {
                                this.$message.success('批量删除成功')
                            } else {
                                this.$message.error('批量删除失败:' + res.msg)
                            }
                            this.load(this.pageNum) //刷新表格
                        })
                })
                .catch(() => {}) //catch捕捉先不做处理
        },
        //批量导出
        exportBatch() {
            //若没有勾选默认导出全部数据，或根据搜索参数
            let param
            if (!this.ids.length) {
                //在JwtInterceptor.java中内置了URL传递token的方式，$request中通过请求头的方式
                param = '&username=' + this.username + '&name=' + this.name
            } else {
                param = '&ids=' + this.ids.join(',')
            }
            window.open(
                this.$apiUrl +
                    '/user/exportExcel?token=' +
                    this.user.token +
                    param
            )
        },
        //选中导入文件后事件
        handleImport(res, file, fileList) {
            if (res.code === '200') {
                this.$message.success('导入成功')
                this.load(this.pageNum)
            } else {
                this.$message.error(res.msg)
            }
        },
        //批量导入，组件直接url
        importBatch() {},
        //下载导入模板
        downloadTemplate() {
            let param = '&type=template'
            window.open(
                this.$apiUrl +
                    '/user/exportExcel?token=' +
                    this.user.token +
                    param
            )
        },
        closeDialog(){
          //清除rules提示信息
          this.$refs.formRef.clearValidate()
        },
        getStatusText(status) {
            switch (status) {
                case 0:
                    return '未激活'
                case 1:
                    return '在线'
                case 2:
                    return '离线'
                case 3:
                    return '冻结'
                default:
                    return '未知'
            }
        },
        getStatusType(status) {
            switch (status) {
                case 0:
                    return 'info'
                case 1:
                    return 'success'
                case 2:
                    return 'danger'
                case 3:
                    return 'warning'
                default:
                    return 'info' // 默认没有特殊样式
            }
        },
        getComputerText(status) {
            switch (status) {
                case 0:
                    return '未绑定'
                case 1:
                    return '在线'
                case 2:
                    return '离线'
                case 3:
                    return '冻结'
                default:
                    return '未知'
            }
        },
    },
}
</script>

<style scoped>
.avatar-uploader-icon {
    font-size: 28px;
    color: #8c939d;
    width: 178px;
    height: 178px;
    line-height: 178px;
    text-align: center;
    border-radius: 50%;
}
.avatar {
    width: 178px;
    height: 178px;
    display: block;
    border-radius: 50%;
}
</style>